package com.heritcoin.coin.lib.util.bitmap

import android.graphics.*
import android.media.ExifInterface
import android.util.Log
import android.util.Size
import android.view.View

import java.io.File

/**
 * created tsts
 * 2023/6/27
 */
object BitmapUtils {

    private val shapePaint: Paint = Paint(Paint.DITHER_FLAG or Paint.FILTER_BITMAP_FLAG or Paint.ANTI_ALIAS_FLAG)
    private val bitmapPaint: Paint = Paint(Paint.DITHER_FLAG or Paint.FILTER_BITMAP_FLAG or Paint.ANTI_ALIAS_FLAG).apply {
        xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_IN)
    }

    private fun getImageRotation(imagePath: String): Float {
        var rotation = 0f
        when (ExifInterface(imagePath).getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL)) {
            ExifInterface.ORIENTATION_ROTATE_90 -> {
                rotation = 90f
            }

            ExifInterface.ORIENTATION_ROTATE_180 -> {
                rotation = 180f
            }

            ExifInterface.ORIENTATION_ROTATE_270 -> {
                rotation = 270f
            }
        }
        return rotation
    }

    /**
     * 相机预览区域放大了，转换成真实比例
     */
    fun getRealImageSize(mPreview: View): Size {
        val cameraPreviewWidth = 3f
        val cameraPreviewHeight = 4f
        if ((mPreview.height.toFloat() / mPreview.width) >= (cameraPreviewHeight / cameraPreviewWidth)) {
            //截取指定区域
            val width = mPreview.height * cameraPreviewWidth / cameraPreviewHeight //手机比 大于 9：16  拍出来的图真实宽度（相对屏幕高度）
            Log.e("tag", "width = $width  预览宽度 = ${mPreview.width}")
            //预览图的宽度
            return Size(width.toInt(), mPreview.height)
        } else {
            //截取指定区域
            val height = mPreview.width * cameraPreviewHeight / cameraPreviewWidth //手机比 小于 9：16  拍出来的图真实宽度（相对屏幕宽度）
            Log.e("tag", "height = $height  预览高度 = ${mPreview.height}")
            return Size(mPreview.width, height.toInt())
        }
    }

    /**
     * 截取bitmap中的指定区域 相机拍摄截取圆圈中的区域
     * @param mPreview 预览的View
     * @param maskView 截取的框框
     * @param targetAspectRatio CameraX预览图的真实比例 4/3 或者 16/9
     * @param isCircle 是圆形的时候 有误差，maskView.width / maskView.height = 602 / 601
     */
    fun bitmapCropping(bitmapFile: File, mPreview: View, maskView: View, isCircle: Boolean): Bitmap? {
        val cameraPreviewWidth = 3f
        val cameraPreviewHeight = 4f
        val maskViewLocation = IntArray(2)
        maskView.getLocationInWindow(maskViewLocation)

        val previewLocation = IntArray(2)
        mPreview.getLocationInWindow(previewLocation)

        val leftOffset = maskViewLocation[0] - previewLocation[0] //获取两个View左边的距离
        val topOffset = maskViewLocation[1] - previewLocation[1] //获取两个View顶部的距离

        val rotation = getImageRotation(bitmapFile.absolutePath)
        val option = BitmapFactory.Options()
        option.inJustDecodeBounds = true
        BitmapFactory.decodeFile(bitmapFile.absolutePath, option)
        val bitmapWidth = if (rotation == 90f || rotation == 270f) option.outHeight else option.outWidth
        val bitmapHeight = if (rotation == 90f || rotation == 270f) option.outWidth else option.outHeight
        Log.e("tag", "图片旋转角度 = ${rotation} ,bitmapWidth = $bitmapWidth ,bitmapHeight = $bitmapHeight")
        option.inPreferredConfig = Bitmap.Config.ARGB_8888
        option.inJustDecodeBounds = false
        var x = 0f
        var y = 0f
        var croppingBitmapWidth = 0f
        var croppingBitmapHeight = 0f
        if ((mPreview.height.toFloat() / mPreview.width) >= (cameraPreviewHeight / cameraPreviewWidth)) {
            //截取指定区域
            val width = mPreview.height * cameraPreviewWidth / cameraPreviewHeight //手机比 大于 9：16  拍出来的图真实宽度（相对屏幕高度）
            Log.e("tag", "width = $width  预览宽度 = ${mPreview.width}")
            //预览图的宽度在原图的百分比位置
            x = bitmapWidth * ((width - maskView.width) / 2f / width) //原图 * 比例位置
            y = bitmapHeight * (topOffset.toFloat() / mPreview.height)
            val bitmapSize = bitmapHeight * (maskView.height.toFloat() / mPreview.height)//高度没变，高度为基准计算
            croppingBitmapHeight = bitmapHeight * (maskView.height.toFloat() / mPreview.height)
            if (isCircle) {
                croppingBitmapWidth = croppingBitmapHeight
            } else {
                //根据裁剪的比例来计算
                croppingBitmapWidth = croppingBitmapHeight / maskView.height * maskView.width
            }
            Log.e("tag", "bitmapSize = $bitmapSize croppingBitmapHeight = $croppingBitmapHeight croppingBitmapWidth = $croppingBitmapWidth")
        } else {
            //截取指定区域
            val height = mPreview.width * cameraPreviewHeight / cameraPreviewWidth //手机比 小于 9：16  拍出来的图真实宽度（相对屏幕宽度）
            Log.e("tag", "height = $height  预览高度 = ${mPreview.height}")
            //预览图的高度在原图的百分比位置
            x = bitmapWidth * (leftOffset.toFloat() / mPreview.width) //原图 * 比例位置
            //比预览高度多出的成像高度 除以2得到顶部的高度 在加上 圆圈的顶部到预览控件的距离，得到圆圈顶部距离整个成像顶部的距离
            val topY = (height - mPreview.height) / 2 + topOffset
            y = bitmapHeight * (topY / height) //原图 * 比例位置
            val bitmapSize = bitmapWidth * (maskView.width.toFloat() / mPreview.width)
            croppingBitmapWidth = bitmapWidth * (maskView.width.toFloat() / mPreview.width)
            if (isCircle) {
                croppingBitmapHeight = croppingBitmapWidth
            } else {
                croppingBitmapHeight = croppingBitmapWidth / maskView.width * maskView.height
            }
            Log.e("tag", "bitmapSize = $bitmapSize croppingBitmapHeight = $croppingBitmapHeight croppingBitmapWidth = $croppingBitmapWidth")
        }

        val left = x
        val top = y
        val right = x + croppingBitmapWidth
        val bottom = y + croppingBitmapHeight
        val rect = Rect(left.toInt(), top.toInt(), right.toInt(), bottom.toInt())
        //旋转回来
        val decoder = BitmapRegionDecoder.newInstance(bitmapFile.absolutePath)
        val newBitmap = decoder?.decodeRegion(rect, option, rotation)
        decoder?.recycle()

        return newBitmap
    }

    /**
     * 裁剪成圆形
     * @param destWidth 需要的圆形图片大小
     */
    fun circleCrop(source: Bitmap?, destWidth: Int, destHeight: Int): Bitmap? {
        if (source == null) {
            return null
        }
        val destMinEdge: Int = Math.min(destWidth, destHeight)
        val radius = destMinEdge / 2f
        val srcWidth: Int = source.width
        val srcHeight: Int = source.height
        val scaleX = destMinEdge / srcWidth.toFloat()
        val scaleY = destMinEdge / srcHeight.toFloat()
        val maxScale = Math.max(scaleX, scaleY)
        val scaledWidth = maxScale * srcWidth
        val scaledHeight = maxScale * srcHeight
        val left = (destMinEdge - scaledWidth) / 2f
        val top = (destMinEdge - scaledHeight) / 2f
        val destRect = RectF(left, top, left + scaledWidth, top + scaledHeight)
        val result = Bitmap.createBitmap(destMinEdge, destMinEdge, Bitmap.Config.ARGB_8888)
        result.setHasAlpha(true)
        val canvas = Canvas(result)
        canvas.drawCircle(radius, radius, radius, shapePaint)
        canvas.drawBitmap(source, null, destRect, bitmapPaint)
        canvas.setBitmap(null)
        return result
    }

    /**
     * 截取bitmap的指定区域
     */
    fun cropBitmap(originalBitmap: Bitmap, rect: RectF): Bitmap? {
        val originalWidth = originalBitmap.width
        val originalHeight = originalBitmap.height

        // 计算裁剪区域左上角点
        val left = rect.left * originalWidth
        val top = rect.top * originalHeight
        val right = rect.right * originalWidth
        val bottom = rect.bottom * originalHeight

        // 构建裁剪区域矩形
        val cropRect = Rect(left.toInt(), top.toInt(), right.toInt(), bottom.toInt())

        kotlin.runCatching {
            return Bitmap.createBitmap(originalBitmap, cropRect.left, cropRect.top, cropRect.width(), cropRect.height())
        }.exceptionOrNull()?.printStackTrace()
        return null
    }


    /**
     * 获取bitmap的平均亮度值 设置阈值，例如 128
     */
    fun getBitmapAverageLuminance(bitmap: Bitmap?): Double? {
        if (bitmap == null) return null
        val width = bitmap.width
        val height = bitmap.height
        var totalLuminance = 0.0

        for (x in 0 until width) {
            for (y in 0 until height) {
                val pixel = bitmap.getPixel(x, y)
                // 将颜色分解成 R、G、B 分量
                val red = (pixel shr 16) and 0xFF
                val green = (pixel shr 8) and 0xFF
                val blue = pixel and 0xFF

                // 根据公式计算亮度值
                val luminance = 0.299 * red + 0.587 * green + 0.114 * blue
                totalLuminance += luminance
            }
        }

        // 计算平均亮度 范围大致在0到255之间
        val averageLuminance = totalLuminance / (width * height)

        //Log.d("CameraX", "平均亮度 = $averageLuminance ")
        return averageLuminance
    }
}